/* Die Klasse GUI_Anschaffungsvorschlag erzeugt die graphische Ober-
 * flaeche fuer einen Anschaffungsvorschlag, der beim System einge-
 * reicht werden kann.
 * 
 * 
 * Datei: GUI_Anschaffungsvorschlag.java
 * Autor: Antonia Wagner 
 * 
 * Datum: 03.12.11                     Version: 0.1 
 * 
 * Historie: 03.12.11 v0.1 von Autor erstellt, die spezifizierten 
 *                         Felder erstellt
 */

package personenverwaltung;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import GUI.Dashboard;
import basis.lokal.Lokalisierung;
import basis.lokal.Sprachen;

public class GUI_Anschaffungsvorschlag
{
  /*
   * Definition benoetigter Konstanten
   */
  private static final int ANZAHL_ZEILEN = 12;
  private static final int ANZAHL_SPALTEN = 2;
  private static final int ANZAHL_ZIFFERN_FELDER = 5;
  private static final int ANZAHL_FELDER = 11;
  private static final int ANZAHL_PFLICHTFELDER = 4;

  /*
   * Fuer die Darstelltun, Verwaltung und Internationalisierung
   * benoetigte Konstanten
   */
  private Lokalisierung lokal;
  private JPanel panel;
  private Vorgangsverwaltung vorgVerwaltung;
  private Benutzer benutzer;

  /*
   * Die Eingabefelder und die dazugehoerige Beschriftung als Listen
   */
  private ArrayList<String> ziffernFelder;
  private ArrayList<String> bezeichnerEingabefelder;
  private HashMap<String, JTextField> eingabeFelder;
  private HashMap<String, JLabel> felderBeschriftungen;
  private ArrayList<String> pflichtfelder;
  /*
   * Die benoetigten Schaltflaechen (Buttons)
   */
  private JButton absendenButton;
  private JButton loeschenButton;


  public GUI_Anschaffungsvorschlag (Vorgangsverwaltung vorgVerwaltung,
      Benutzer benutzer)
  {
    /*
     * Parameter speichern
     */
    this.vorgVerwaltung = vorgVerwaltung;
    this.benutzer = benutzer;

    /*
     * Listen erzeugen
     */
    ziffernFelder = new ArrayList<String> ();
    bezeichnerEingabefelder = new ArrayList<String> ();
    eingabeFelder = new HashMap<String, JTextField> ();
    felderBeschriftungen = new HashMap<String, JLabel> ();
    pflichtfelder = new ArrayList<String> ();

    /*
     * Sprache abfragen und speichern
     */
    Sprachen sprache = Dashboard.verwendeteSprache ();
    setzeSprache (sprache.toString ());
  }


  /**
   * 
   * @return den von der Klasse erzeugten JPanel zur Verwendung in einer
   *         grafischen Vater-Oberflaeche
   */
  public JPanel gibPanel ()
  {
    return panel;
  }


  /**
   * Fuegt die Eingabefelder und deren Beschriftung der graphischen
   * Oberflaeche hinzu
   */
  private void felderHinzufuegen ()
  {
    /*
     * Erzeugt ein neues JPanel mit der benoetigten Anzahl an Zeilen und
     * Spalten
     */
    panel = new JPanel ();
    panel.setLayout (new GridLayout (ANZAHL_ZEILEN, ANZAHL_SPALTEN));

    /*
     * Fuegt alle Eingabefelder und deren Beschriftungsfelder ein
     */
    for (int i = 0; i < ANZAHL_FELDER; i++)
    {
      /*
       * Beschriftung einfuegen
       */
      panel.add (felderBeschriftungen.get (bezeichnerEingabefelder
          .get (i)));
      /*
       * Textfeld einfuegen
       */
      panel.add (eingabeFelder.get (bezeichnerEingabefelder.get (i)));
    }

    /*
     * Fuegt die benoetigten Schaltflaechen ein
     */
    panel.add (absendenButton);
    panel.add (loeschenButton);

    panel.setVisible (true);
  }


  /**
   * Implementierung der ActionListener fur die Schaltflaechen
   */
  private void actionListenerEinfuegen ()
  {
    absendenButton.addActionListener (new ActionListener ()
    {
      @Override
      public void actionPerformed (ActionEvent e)
      {
        anschaffungsvorschlagErzeugen ();
      }
    });

    loeschenButton.addActionListener (new ActionListener ()
    {
      @Override
      public void actionPerformed (ActionEvent arg0)
      {
        alleFelderLoeschen ();
      }
    });
  }


  /**
   * Diese Methode erzeugt aus den eingegebenen Daten den Anschaffungs-
   * vorschlag und speichert ihn fuer weitere Bearbeitungen im System
   * 
   */
  private void anschaffungsvorschlagErzeugen ()
  {
    String titel = eingabeFelder.get ("Titel").getText ();
    String verlag = eingabeFelder.get ("Verlag").getText ();
    String erschJahr = eingabeFelder.get ("Erscheinungsjahr")
        .getText ();
    String anzExmpl = eingabeFelder.get ("Anzahl Exemplare").getText ();

    Anschaffungsvorschlag vorschlag = null;

    /*
     * Pruefen, ob alle erforderlichen Angaben eines Anschaffungs-
     * vorschlags ausgefuellt wurden und einen Anschaffungsvorschlag
     * erzeugen
     */
    if ((titel != null) && (verlag != null) && (erschJahr != null)
        && (anzExmpl != null))
    {
      try
      {
        vorschlag = vorgVerwaltung.anschaffungsvorschlagMachen (
            benutzer, titel, verlag, Integer.decode (erschJahr),
            Integer.decode (anzExmpl));
      }
      catch (NumberFormatException ex)
      {
        pflichtfeldNichtAusgefuellt ();
        return;
      }
      catch (NullPointerException ex)
      {
        System.out.println (ex.getMessage ());
      }
    }
    /*
     * Wenn Felder fehlen, eine Benachrichtigung an den Benutzer
     * herausgeben und die Methode verlassen
     */
    else
    {
      pflichtfeldNichtAusgefuellt ();
      return;
    }

    /*
     * Den Autor setzen
     */
    String text = eingabeFelder.get ("Autor").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeAutor (eingabeFelder.get ("Autor").getText ());
    }
    /*
     * Die Auflage setzen
     */
    text = eingabeFelder.get ("Auflage").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeAuflage (
	  Integer.decode (eingabeFelder.get ("Auflage").getText ()));
    }
    /*
     * Den Erscheinungsort setzen
     */
    text = eingabeFelder.get ("Erscheinungsort").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeErscheinungsort (
          eingabeFelder.get ("Erscheinungsjahr").getText ());
    }
    /*
     * ISBN setzen
     */
    text = eingabeFelder.get ("ISBN").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeIsbn (eingabeFelder.get ("ISBN").getText ());
    }
    /*
     * Stueckpreis setzen
     */
    text = eingabeFelder.get ("Preis").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeStueckpreis (Long.decode (eingabeFelder.get (
          "Preis").getText ()));
    }
    /*
     * Anzahl der Praesenzexemplare setzen
     */
    text = eingabeFelder.get ("Anzahl Exemplare Lesehalle").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeAnzExemplareLesehalle (Integer
          .decode (eingabeFelder.get ("Anzahl Exemplare Lesehalle")
              .getText ()));
    }
    /*
     * Bemerkung setzen
     */
    text = eingabeFelder.get ("Bemerkung").getText ();
    if ((text != null) && (text.length () > 0))
    {
      vorschlag.setzeBemerkung (
          eingabeFelder.get ("Bemerkung").getText ());
    }
    /*
     * Eine Meldung an den Benutzer rausgeben, dass der Vorschlag
     * erfolgreich beim System angekommen ist
     */
    JOptionPane.showMessageDialog (null,
            lokal.gibUebersetzung ("Erfolgreich abgesendet"),
            lokal.gibUebersetzung ("Info"),
            JOptionPane.INFORMATION_MESSAGE);

    /*
     * Fuer einene weiteren Vorschlag werden alle Felder zurueckgesetzt
     */
    alleFelderLoeschen ();
  }


  /**
   * Alle Pflichtfelder als solche erkennbar machen
   */
  private void pflichtfelderMarkieren ()
  {
    for (int i = 0; i < ANZAHL_PFLICHTFELDER; i++)
    {
      String schlagwort = pflichtfelder.get (i);
      String text = felderBeschriftungen.get (schlagwort).getText ();
      text += "*";
      felderBeschriftungen.get (schlagwort).setText (text);
    }
  }


  /**
   * Speichert alle Schlagwoerter der Felder, in denen nur Ziffern
   * erlaubt sind, um sie ansprechen zu koennen
   */
  private void bezeichnungenZiffernfelderSpeichern ()
  {
    ziffernFelder.add ("Erscheinungsjahr");
    ziffernFelder.add ("Anzahl Exemplare");
    ziffernFelder.add ("Auflage");
    ziffernFelder.add ("Preis");
    ziffernFelder.add ("Anzahl Exemplare Lesehalle");
  }


  /**
   * Speichert alle Schlagwoerter fuer die Beschriftungen der Felder
   */
  private void bezeichnungenEingabefelderSpeichern ()
  {
    bezeichnerEingabefelder.add ("Titel");
    bezeichnerEingabefelder.add ("Autor");
    bezeichnerEingabefelder.add ("Verlag");
    bezeichnerEingabefelder.add ("ISBN");
    bezeichnerEingabefelder.add ("Auflage");
    bezeichnerEingabefelder.add ("Preis");
    bezeichnerEingabefelder.add ("Erscheinungsort");
    bezeichnerEingabefelder.add ("Erscheinungsjahr");
    bezeichnerEingabefelder.add ("Anzahl Exemplare");
    bezeichnerEingabefelder.add ("Anzahl Exemplare Lesehalle");
    bezeichnerEingabefelder.add ("Bemerkung");
  }


  /**
   * Die Eingaben in Textfelder, in denen nur Ziffern erlaubt sind
   * werden durch das Aendern in Integer-Dokumente entsprechend
   * beschraenkt
   */
  private void erzeugeZiffernFelder ()
  {
    String schlagwort;
    for (int i = 0; i < ANZAHL_ZIFFERN_FELDER; i++)
    {
      /*
       * Die Textfelder, die Ziffern als Eingabe erwarten entsprechend
       * einrichten
       */
      schlagwort = ziffernFelder.get (i);
      JTextField feld = eingabeFelder.get (schlagwort);
      feld.setDocument (new IntegerDokument ());
    }
  }


  /**
   * Erzeugt die Textfelder, in denen Buchstaben erlaubt sind
   */
  private void erzeugeEingabefelder ()
  {
    String schlagwort;
    String beschriftung;
    for (int i = 0; i < ANZAHL_FELDER; i++)
    {
      /*
       * Die Textfelder erzeugen
       */
      schlagwort = bezeichnerEingabefelder.get (i);
      eingabeFelder.put (schlagwort, new JTextField ());

      /*
       * Die Beschriftungen des dazugehoerigen JLabel erzeugen und
       * einruecken
       */
      beschriftung = "  " + lokal.gibUebersetzung (schlagwort) + "  ";
      felderBeschriftungen.put (schlagwort, new JLabel (beschriftung));
    }
  }


  /**
   * Setzt alle Eingabefelder zurueck
   */
  private void alleFelderLoeschen ()
  {
    JTextField feld;
    /*
     * Alle Felder zureucksetzen
     */
    for (int i = 0; i < ANZAHL_FELDER; i++)
    {
      feld = eingabeFelder.get (bezeichnerEingabefelder.get (i));
      feld.setText (null);
    }

    /*
     * Falls die Pflichtfelder rot markiert waren, werden sie wieder in
     * neutrales weiss gesetzt
     */
    for (int i = 0; i < ANZAHL_PFLICHTFELDER; i++)
    {
      feld = eingabeFelder.get (pflichtfelder.get (i));
      feld.setBackground (Color.WHITE);
    }
  }


  /**
   * Das Speichern der Pflichtfelder, um sie markieren und abfragen zu
   * koennen
   */
  private void pflichtfelderSpeichern ()
  {
    pflichtfelder.add ("Titel");
    pflichtfelder.add ("Verlag");
    pflichtfelder.add ("Erscheinungsjahr");
    pflichtfelder.add ("Anzahl Exemplare");
  }


  /**
   * Fehlermeldung an den Benutzer, wenn ein oder mehrere Pflichtfelder
   * nicht ausgefuellt wurden und Erzeugen einer Markierung der
   * Pflichfelder
   */
  private void pflichtfeldNichtAusgefuellt ()
  {
    JOptionPane.showMessageDialog (null,
        lokal.gibUebersetzung ("Pflichtfeld nicht ausgefuellt"),
        lokal.gibUebersetzung ("Fehler"), JOptionPane.ERROR_MESSAGE);

    for (int i = 0; i < ANZAHL_PFLICHTFELDER; i++)
    {
      JTextField feld = eingabeFelder.get (pflichtfelder.get (i));

      String text = feld.getText ();
      if ((text == null) || (text.length () == 0))
      {
        feld.setBackground (Color.RED);
      }
    }
  }


  private void schaltfaechenErzeugen ()
  {
    /*
     * Schaltflaechen erzeugen
     */
    absendenButton = new JButton (lokal.gibUebersetzung ("absenden"));
    loeschenButton = new JButton (lokal.gibUebersetzung ("loeschen"));
  }


  /*
   * Einige Initialisierungsaufrufe vornehmen
   */
  private void initialisieren ()
  {
    /*
     * Initialisierung der Listen und Erzeugen der Felder
     */
    schaltfaechenErzeugen ();
    pflichtfelderSpeichern ();
    bezeichnungenZiffernfelderSpeichern ();
    bezeichnungenEingabefelderSpeichern ();
    erzeugeEingabefelder ();
    erzeugeZiffernFelder ();

    /*
     * GUI initialisieren
     */
    actionListenerEinfuegen ();
    pflichtfelderMarkieren ();
    felderHinzufuegen ();
  }

  /*
   * Die private Klasse ist dafuer zustaendig, dass in einem Eingabe-
   * feld nur Ziffern eingegeben werden koennen. Diese Einschraenkung
   * ist notwendig, um Fehler beim Parsen von String in Integer zu ver-
   * meiden.
   */
  private class IntegerDokument extends PlainDocument
  {

    private static final long serialVersionUID = -7436588918551371930L;

    public void insertString (int offset, String s,
        AttributeSet attributeSet) throws BadLocationException
    {
      try
      {
        Integer.parseInt (s);
      }
      catch (NumberFormatException nfex)
      {
        JOptionPane.showMessageDialog (null,
                lokal.gibUebersetzung ("Nur Ziffern"),
                lokal.gibUebersetzung ("Fehler"),
                JOptionPane.ERROR_MESSAGE);
        return;
      }
      super.insertString (offset, s, attributeSet);
    }
  }


  /**
   * @param sprache
   *          die verwendet werden soll
   */
  public void setzeSprache (String sprache)
  {
    lokal = new Sprachverwaltung (sprache).gibLokalisierung ();

    /*
     * Beim Aendern der Sprache muss neu initialisiert werden
     */
    initialisieren ();
  }
}
